package com.example.invoke.controller;

import com.example.invoke.entity.User;
import com.example.invoke.listener.CommonEvent;
import com.example.invoke.service.IndexService;
import com.google.common.collect.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.core.io.ClassPathResource;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.data.redis.core.script.RedisScript;
import org.springframework.scripting.support.ResourceScriptSource;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Map;

@RestController
public class IndexController {
    @Autowired
    private IndexService indexService;


    @GetMapping(value = "handle")
    public String handle (@RequestParam Map source) {
        return indexService.handle(source);
    }

    @GetMapping(value = "getA")
    public String getA (@RequestParam Map source) {
        System.out.println(source.toString());
        return indexService.getA("aa", null);
    }

    @GetMapping(value = "add")
    public User add (String name) {
        return indexService.addUser(name);
    }

    @GetMapping(value = "param")
    public String param (HttpServletRequest request, @RequestParam("index") Integer index, @RequestParam Map source) {
        System.out.println(index);
        System.out.println(source.toString());
        System.out.println(getIp(request));
        return "";
    }

    private String getIp(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        System.out.println("x-forwarded-for ip: " + ip);
        if (ip != null && ip.length() != 0 && !"unknown".equalsIgnoreCase(ip)) {
            // 多次反向代理后会有多个ip值，第一个ip才是真实ip
            if( ip.indexOf(",")!=-1 ){
                ip = ip.split(",")[0];
            }
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
            System.out.println("Proxy-Client-IP ip: " + ip);
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
            System.out.println("WL-Proxy-Client-IP ip: " + ip);
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_CLIENT_IP");
            System.out.println("HTTP_CLIENT_IP ip: " + ip);
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
            System.out.println("HTTP_X_FORWARDED_FOR ip: " + ip);
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("X-Real-IP");
            System.out.println("X-Real-IP ip: " + ip);
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
            System.out.println("getRemoteAddr ip: " + ip);
        }
        System.out.println("获取客户端ip: " + ip);
        return ip;
    }


    @PostMapping(value = "p/{index}")
    public String p (HttpServletRequest request, @PathVariable("index") Integer index, @RequestBody Map source) {
        System.out.println(index);
        System.out.println(source.toString());
        Runtime.getRuntime().addShutdownHook(new Thread(() -> System.out.println("addShutdownHook")));
        return "";
    }

    @Autowired
    private ApplicationContext applicationContext;

    @GetMapping(value = "bean/{name}")
    public String bean (@PathVariable("name") String name) {
        Object bean = applicationContext.getBean(name);
        if (bean == null) {
            return "null";
        }
        return bean.getClass().getName();
    }

    @GetMapping(value = "listener")
    public String listener () {
        applicationContext.publishEvent(CommonEvent.getInstance("aaa", "111"));
        return "listener";
    }

    @Autowired
    private StringRedisTemplate redisTemplate;


    @Bean(name = "t")
    public DefaultRedisScript<List> defaultRedisScript() {
        DefaultRedisScript<List> defaultRedisScript = new DefaultRedisScript<>();
        defaultRedisScript.setScriptSource(new ResourceScriptSource(new ClassPathResource("redis/incr.lua")));

        defaultRedisScript.setResultType(List.class);
        return defaultRedisScript;
    }

    @Autowired
    @Qualifier("t")
    private RedisScript redisScript;

    @GetMapping(value = "redis")
    public String redis () {

        if (!redisTemplate.hasKey("ip")) {
            ValueOperations<String, String> ops = redisTemplate.opsForValue();
            ops.set("ip", "0");
        }

        List<String> keys = Lists.newArrayList("ip");

        Object execute = redisTemplate.execute(redisScript, keys, String.valueOf(1000 * 60));
        return execute.toString();
    }

}
